﻿// Roadblocks 最短路计数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*
https://loj.ac/p/10076

原题来自：USACO 2006 Nov. Gold

贝茜把家搬到了一个小农场，但她常常回到 FJ 的农场去拜访她的朋友。贝茜很喜欢路边的风景，不想那么快地结束她的旅途，
于是她每次回农场，都会选择第二短的路径，而不象我们所习惯的那样，选择最短路。

贝茜所在的乡村有 R(1 <= R <= 10^5) 条双向道路，每条路都连接了所有的 N(1 <= N <= 5000) 个农场中的某两个。
贝茜居住在农场 1，她的朋友们居住在农场 N（即贝茜每次旅行的目的地）。

贝茜选择的第二短的路径中，可以包含任何一条在最短路中出现的道路，并且一条路可以重复走多次。
当然第二短路的长度必须严格大于最短路（可能有多条）的长度，但它的长度必须不大于所有除最短路外的路径的长度。

一句话题意：给一张无向图，求这张图的严格次短路之长。

输入格式
输入文件的第 1 行为两个整数，N 和 R，用空格隔开；

第 2 ~~ R+1 行：每行包含三个用空格隔开的整数 A、B 和 D，表示存在一条长度为 D(1 <= D <= 5000) 的路连接农场 A 和农场 B。

输出格式
输出仅一个整数，表示从农场 1 到农场 N 的第二短路的长度。


输入 
4 4
1 2 100
2 4 200
2 3 250
3 4 100
输出
450

4 5
1 2 100
2 4 200
2 3 100
3 4 100
1 4 301


301

最短路：1 -> 2 -> 4（长度为 100+200=300） 第二短路：1 -> 2 -> 3 -> 4（长度为 100+250+100=450）
*/


#include <iostream>
#include <cstring>
#include <queue>


using namespace std;

const int M = 2e5 + 10;
const int N = 5010;
int h[N], e[M], ne[M],w[M], idx;
int n, m;
int dist[N][2];		// 存储所有点到1号点的距离
bool st[N][2];		// 存储每个点的最短距离是否已确定


struct ELE {
	int id, type, dist;
	// 重载 > 运算符，用于优先队列的greater比较
	bool operator > (const ELE& t) const {
		return dist > t.dist;  // 按距离从小到大排序
	}
};

void add(int a, int b, int l) {
	e[idx] = b,w[idx]=l, ne[idx] = h[a], h[a] = idx++;
}


void dijkstra() {
	memset(dist, 0x3f, sizeof dist);
	memset(st, 0, sizeof st);

	dist[1][0] = 0;
	priority_queue<ELE, vector<ELE>, greater<ELE>> heap;
	heap.push({ 1,0, 0 });      // first存储距离，second存储节点编号

	while (!heap.empty()) {
		ELE t = heap.top();heap.pop();
		int id = t.id; int type = t.type; int distance = t.dist;
		if (st[id][type] == true) continue;
		st[id][type] = true;

		for (int i = h[id]; i != -1; i = ne[i]) {
			int j = e[i]; int d = w[i];
			if (j == 4) {
				int deg = 9;
			}
			if (dist[j][0] > d + distance) {
				dist[j][1] = dist[j][0];
				dist[j][0] = d + distance;
				heap.push({j,0,dist[j][0]});
				heap.push({ j,1,dist[j][1] });
			}
			else if (dist[j][1] > d + distance && d + distance > dist[j][0]) {
				dist[j][1] = d + distance;
				heap.push({ j,1,dist[j][1] });
			}
		}
	}

	if (dist[n][1] > 0x3f3f3f3f / 2) {
		cout << -1 << endl;
	}
	else {
		cout << dist[n][1] << endl;
	}

	return;
}


int main()
{
	memset(h, -1, sizeof h);
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		int a, b, l; cin >> a >> b >> l;
		add(a, b, l); add(b, a, l);
	}

	dijkstra();


	return 0;
}

 